home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / vmalloc.c < prev    next >
Text File  |  1993-12-06  |  4KB  |  140 lines

  1. /** 
  2.  ** VMALLOC.C 
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "gmalloc.h"
  25.  
  26. typedef struct _vnode_ {
  27.     struct _vnode_ *next;
  28.     char far       *addr;
  29.     unsigned int   size;
  30. } vnode;
  31.  
  32. static vnode *freelist = NULL;  /* list of free memory blocks */
  33. static vnode *usedlist = NULL;  /* list of used memory blocks */
  34. static vnode *nodelist = NULL;  /* list of available nodes    */
  35.  
  36. #define NODEALLOC 10        /* allocate this many nodes at once */
  37. #define MINSIZE      16        /* smallest block size */
  38.  
  39. static vnode *getnode(void)
  40. {
  41.     vnode *np;
  42.     int   count;
  43.  
  44.     if(nodelist == NULL) {
  45.         np = _GrMalloc(sizeof(vnode) * NODEALLOC);
  46.         if(np == NULL) return(NULL);
  47.         for(count = NODEALLOC; --count >= 0; np++) {
  48.         np->next = nodelist;
  49.         nodelist = np;
  50.         }
  51.     }
  52.     np = nodelist;
  53.     nodelist = np->next;
  54.     return(np);
  55. }
  56.  
  57. void _GrVidMemInit(char far *start,unsigned int size)
  58. {
  59.     vnode *np;
  60.  
  61.     if(freelist != NULL) {
  62.         for(np = freelist; np->next != NULL; np = np->next);
  63.         np->next = nodelist;
  64.         nodelist = freelist;
  65.         freelist = NULL;
  66.     }
  67.     if(usedlist != NULL) {
  68.         for(np = usedlist; np->next != NULL; np = np->next);
  69.         np->next = nodelist;
  70.         nodelist = usedlist;
  71.         usedlist = NULL;
  72.     }
  73.     if((size > MINSIZE) && ((np = getnode()) != NULL)) {
  74.         np->next = NULL;
  75.         np->addr = start;
  76.         np->size = size;
  77.         freelist = np;
  78.     }
  79. }
  80.  
  81. char far *_GrVidAlloc(unsigned int size)
  82. {
  83.     vnode *np,*new,*prev;
  84.  
  85.     for(np = freelist,prev = NULL; np != NULL; prev = np,np = np->next) {
  86.         if(np->size >= size) {
  87.         if((np->size >= (size + MINSIZE)) && ((new = getnode()) != NULL)) {
  88.             new->size = size;
  89.             new->addr = np->addr + (np->size - size);
  90.             np->size -= size;
  91.             new->next = usedlist;
  92.             usedlist  = new;
  93.             return(new->addr);
  94.         }
  95.         *((prev == NULL) ? &freelist : &prev->next) = np->next;
  96.         np->next = usedlist;
  97.         usedlist = np;
  98.         return(np->addr);
  99.         }
  100.     }
  101.     return((char far *)NULL);
  102. }
  103.  
  104. void _GrVidFree(char far *addr)
  105. {
  106.     vnode *np,*fp,*prev;
  107.  
  108.     for(np = usedlist,prev = NULL; ; prev = np,np = np->next) {
  109.         if(np == NULL) return;
  110.         if(np->addr == addr) break;
  111.     }
  112.     *((prev == NULL) ? &usedlist : &prev->next) = np->next;
  113.     for(fp = freelist,prev = NULL; fp != NULL; prev = fp,fp = fp->next) {
  114.         if(fp->addr > np->addr) {
  115.         if(fp->addr == (np->addr + np->size)) {
  116.             fp->size += np->size;
  117.             fp->addr = np->addr;
  118.             np->next = nodelist;
  119.             nodelist = np;
  120.             np = fp;
  121.             fp = fp->next;
  122.         }
  123.         break;
  124.         }
  125.     }
  126.     np->next = fp;
  127.     if(prev == NULL)
  128.         freelist = np;
  129.     else if(np->addr != (prev->addr + prev->size))
  130.         prev->next = np;
  131.     else {
  132.         prev->size += np->size;
  133.         prev->addr = np->addr;
  134.         prev->next = fp;
  135.         np->next = nodelist;
  136.         nodelist = np;
  137.     }
  138. }
  139.  
  140.